package com.hjx.windowtool.video.combine;

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSplitPane;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JSlider;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter.ToIplImage;

import com.hjx.windowtool.util.AudioPlayback;

import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.awt.event.ActionEvent;

public class VideoPlayerApp {

	private JFrame frame;
	private JTable table;
	private JPanel panel_main;
	private JLabel panel_preview;
	int width;
	int height;
	private JSlider slider;
	private boolean isPlay=false;
	int frameNumber=0;
	int lengthInFrames;
	private FFmpegFrameGrabber grab;
	
	private boolean handChangeFrame=false;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
					VideoPlayerApp window = new VideoPlayerApp();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public VideoPlayerApp() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 422, 179);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(1.0);
		frame.getContentPane().add(splitPane, BorderLayout.CENTER);
		
		JScrollPane scrollPane = new JScrollPane();
		splitPane.setRightComponent(scrollPane);
		
		table = new JTable();
		scrollPane.setViewportView(table);
		
		JPanel panel = new JPanel();
		splitPane.setLeftComponent(panel);
		panel.setLayout(new BorderLayout(0, 0));
		
		JPanel panel_1 = new JPanel();
		panel_1.setBorder(new LineBorder(new Color(0, 0, 0)));
		panel.add(panel_1, BorderLayout.CENTER);
		panel_1.setLayout(new BorderLayout(0, 0));
		
		panel_main = new JPanel();
//		panel_main.setBackground(Color.BLACK);
		panel_1.add(panel_main, BorderLayout.CENTER);
		panel_main.setLayout(null);
		panel_main.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				setPreviewSize(width, height);
			}
		});
		
		panel_preview = new JLabel();
//		panel_preview.setBackground(Color.BLACK);
		panel_preview.setBounds(121, 2, 279, 308);
		panel_main.add(panel_preview);
		
		slider = new JSlider();
		slider.setMaximum(100);
		slider.setBackground(Color.CYAN);
		slider.setValue(0);
		slider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				System.out.println(slider.getValueIsAdjusting()+"==="+slider.getValue());
				if (!isPlay||!slider.getValueIsAdjusting()) {
					return;
				}
				
				frameNumber=(int) (lengthInFrames/1000d*slider.getValue());
				System.out.println("frameNumber===="+frameNumber);
				handChangeFrame=false;
			}
		});
		panel_1.add(slider, BorderLayout.SOUTH);
		slider.setValue(100);
		
		JPanel panel_2 = new JPanel();
		panel.add(panel_2, BorderLayout.SOUTH);
		
		JButton button = new JButton("预览");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				button.setEnabled(false);
				new Thread(new Runnable() {
					private AudioPlayback audioPlayback;
					private List<Buffer[]> listVoices=new ArrayList<>();
					public void run() {
						grab = new FFmpegFrameGrabber("E:\\迅雷下载\\TheMandalorianS01E03.mp4");
						try {
							grab.start();
							isPlay=true;
							frameNumber=0;
							slider.setValue(0);
							audioPlayback = new AudioPlayback(grab);
							width=grab.getImageWidth();
							height=grab.getImageHeight();
							setPreviewSize(width, height);
							lengthInFrames = grab.getLengthInFrames();
							double frameRate = grab.getFrameRate();
							long millis = (long) (1000 / frameRate);
							System.out.println("frameRate==="+frameRate+";millis="+millis);
							grab.setFrameNumber(0);
							ExecutorService imageExecutorService = Executors.newFixedThreadPool(1);
							ExecutorService audioExecutorService = Executors.newSingleThreadExecutor();
							int lastframeNumber=frameNumber;
							
//							for (int i = 0; i < 100; i++) {
//								Frame f = grab.grab();
//								System.out.println("grab.getFrameNumber()===="+grab.getFrameNumber());
//								System.out.println("f.image==="+f.image);
//								System.out.println("f.sample==="+f.samples);
//							}
							Java2DFrameConverter converter = new Java2DFrameConverter();
							while (isPlay&&frameNumber<=lengthInFrames) {
								try {
									if (frameNumber-lastframeNumber>1||frameNumber-lastframeNumber<0) {
										grab.setFrameNumber(frameNumber);
									}
									Frame f=grab.grabFrame();
									lastframeNumber=frameNumber;
									long currentTimeMillis = System.currentTimeMillis();
									if (f.image != null) {
										Runnable runnable = new Runnable() {
											public void run() {
												BufferedImage image = converter.convert(f);
												Rectangle bounds = panel_preview.getBounds();
												Graphics g = panel_preview.getGraphics();
												((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
												g.drawImage(image, 0, 0, bounds.width, bounds.height, null);
											}
										};
										imageExecutorService.submit(runnable);
									}
									if (f.samples!=null) {
										try {
											audioExecutorService.submit(new Runnable() {
												@Override
												public void run() {
													audioPlayback.processAudio(f.samples);
												}
											}).get();
										} catch (Exception e) {
											
										}
									}
//									long useMillis = System.currentTimeMillis() - currentTimeMillis;
//									System.out.println(millis+"==="+"useMillis==="+useMillis);
//									if (useMillis<millis) {
//										Thread.sleep(millis-useMillis);
//									}
								} catch (Exception e) {
									e.printStackTrace();
								} finally {
									int n = frameNumber*100/lengthInFrames;
									slider.setValue(n);
									frameNumber=grab.getFrameNumber();
									System.out.println("========"+frameNumber);
								}
								
							}
							
						} catch (Exception e1) {
							e1.printStackTrace();
						}finally {
							try {
								grab.close();
								grab=null;
							} catch (Exception e1) {
								e1.printStackTrace();
							}
							button.setEnabled(true);
							isPlay=false;
						}
					}
				}).start();
			}
		});
		panel_2.add(button);
		
		JButton button_1 = new JButton("停止");
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				isPlay = false;
			}
		});
		panel_2.add(button_1);
	}

	/**
	 * 
	 */
	public void setPreviewSize(int width,int height) {
		if (width==0||height==0) {
			panel_preview.setBounds(0, 0, 0, 0);
			return;
		}
		Rectangle bounds = panel_main.getBounds();
		System.out.println(bounds);
		double w = bounds.getWidth();
		double h = bounds.getHeight();
		int px=0;
		int py=0;
		double ph=h;
		double pw=w;
		if (width>=height) {
			ph=w*height/width;
			pw=w;
			System.out.println(ph);
			if (ph>h) {
				ph=h;
				pw=h/((height*1d)/(width*1d));
				System.out.println(pw);
			}
			System.out.println(pw+"==="+ph);
		}else {
			ph=h;
			pw=h*width/height;
			if(pw>w) {
				pw=w;
				ph=w/(width/(height*1d));
			}
		}
		px=(int) ((w-pw)/2);
		py=(int) ((h-ph)/2);
		panel_preview.setBounds(px, py, (int)pw, (int)ph);
	}
}
